{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import sdm as sdmlib\n",
    "from collections import defaultdict\n",
    "import random\n",
    "import string\n",
    "import time\n",
    "from math import ceil\n",
    "from IPython.display import clear_output\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "#%load_ext line_profiler\n",
    "\n",
    "empty = ' '\n",
    "flip_table = string.maketrans('OX', 'XO')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Player(object):\n",
    "    def __init__(self):\n",
    "        self.stats = defaultdict(int)\n",
    "    \n",
    "    def on_invalid_move(self):\n",
    "        raise Exception('Ops')\n",
    "    \n",
    "    def on_finish(self, winner, seq):\n",
    "        pass\n",
    "    \n",
    "    def next_move(self, step, board):\n",
    "        v = []\n",
    "        for idx, x in enumerate(board):\n",
    "            if x == empty:\n",
    "                v.append(idx)\n",
    "        return random.choice(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class SmartPlayer(object):\n",
    "    def __init__(self):\n",
    "        self.stats = defaultdict(int)\n",
    "    \n",
    "    def on_invalid_move(self):\n",
    "        raise Exception('Ops')\n",
    "    \n",
    "    def on_finish(self, winner, seq):\n",
    "        pass\n",
    "    \n",
    "    def next_move(self, step, board):\n",
    "        v = []\n",
    "        v_block = []\n",
    "        #print('='*20)\n",
    "        #print('board', board)\n",
    "        for idx, x in enumerate(board):\n",
    "            if x == empty:\n",
    "                boardX = board[:idx] + 'X' + board[idx+1:]\n",
    "                winnerX = check_for_winner(boardX)\n",
    "                if winnerX == 'X':\n",
    "                    # Wins the game.\n",
    "                    return idx\n",
    "\n",
    "                boardO = board[:idx] + 'O' + board[idx+1:]\n",
    "                winnerO = check_for_winner(boardO)\n",
    "                if winnerO == 'O':\n",
    "                    # Prevents a defeat.\n",
    "                    v_block.append(idx)\n",
    "                \n",
    "                v.append(idx)\n",
    "        #print('='*20)\n",
    "        if v_block:\n",
    "            return v_block[0]\n",
    "        return random.choice(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class HumanPlayer(object):\n",
    "    def __init__(self):\n",
    "        self.stats = defaultdict(int)\n",
    "    \n",
    "    def on_invalid_move(self):\n",
    "        raise Exception('Ops')\n",
    "    \n",
    "    def on_finish(self, winner, seq):\n",
    "        pass\n",
    "    \n",
    "    def next_move(self, step, board):\n",
    "        #clear_output(wait=True)\n",
    "        while True:\n",
    "            print_board(board)\n",
    "            text = raw_input('Entre com a linha/coluna: ')\n",
    "            if len(text) != 2:\n",
    "                continue\n",
    "            si = text[0]\n",
    "            sj = text[1]\n",
    "            i = int(si)-1\n",
    "            j = int(sj)-1\n",
    "            idx = 3*i+j\n",
    "            if board[idx] == empty:\n",
    "                break\n",
    "        return idx\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class SDMPlayer(object):\n",
    "    def __init__(self, sdm0, sdm1, bs_to_boards, boards_to_bs):\n",
    "        self.bs_to_boards = bs_to_boards\n",
    "        self.boards_to_bs = boards_to_bs\n",
    "        \n",
    "        #self.sdm0 = sdm0\n",
    "        self.sdm1 = sdm1\n",
    "        \n",
    "        self.qty_per_action = self.sdm1.bits // 9\n",
    "        \n",
    "        self.on_finish = self.on_finish1\n",
    "        \n",
    "        self.debug = False\n",
    "        \n",
    "        self.reset_stats()\n",
    "    \n",
    "    def reset_stats(self):\n",
    "        self.stats = defaultdict(int)\n",
    "    \n",
    "    def on_invalid_move(self):\n",
    "        raise Exception('Ops')\n",
    "    \n",
    "    def board_to_bitstring(self, board):\n",
    "        bs = self.boards_to_bs.get(board, None)\n",
    "        if bs is None:\n",
    "            bs = sdmlib.Bitstring.init_random(self.sdm1.bits)\n",
    "            self.bs_to_boards[bs] = board\n",
    "            self.boards_to_bs[board] = bs\n",
    "            #self.sdm0.write(bs, bs)\n",
    "        return bs\n",
    "    \n",
    "    def bitstring_to_board(self, bs):\n",
    "        board = self.bs_to_boards.get(bs, None)\n",
    "        return board\n",
    "    \n",
    "    def flip(self, board):\n",
    "        return board.translate(flip_table)\n",
    "    \n",
    "    def on_finish1(self, winner, seq):\n",
    "        if self.debug:\n",
    "            print('Learning...')\n",
    "        \n",
    "        flip_flag = False\n",
    "        if winner == 'O':\n",
    "            flip_flag = True\n",
    "            winner = winner.translate(flip_table)\n",
    "        \n",
    "        for step, (name, action, board_before, board_after) in enumerate(seq):\n",
    "            board = board_before\n",
    "            if flip_flag:\n",
    "                board = self.flip(board)\n",
    "                name = name.translate(flip_table)\n",
    "            \n",
    "            qty = self.qty_per_action\n",
    "            offset = action*qty\n",
    "            bs_actions = sdmlib.Bitstring.init_random(self.sdm1.bits)\n",
    "\n",
    "            if winner is None:\n",
    "                weight = 1\n",
    "                for i in range(qty):\n",
    "                    bs_actions.set_bit(offset+i, 1)\n",
    "                    \n",
    "                if name == 'O':\n",
    "                    board = self.flip(board)\n",
    "\n",
    "            elif name == winner:\n",
    "                # Positive learning\n",
    "                weight = 2\n",
    "                for i in range(qty):\n",
    "                    bs_actions.set_bit(offset+i, 1)\n",
    "                \n",
    "            else:\n",
    "                # Negative learning\n",
    "                weight = 5\n",
    "                board = self.flip(board)\n",
    "                for i in range(qty):\n",
    "                    bs_actions.set_bit(offset+i, 0)\n",
    "\n",
    "            bs_board = self.board_to_bitstring(board)\n",
    "            if self.debug:\n",
    "                print_board(board)\n",
    "                print(action, weight, self.bs_actions_to_rewards(bs_actions))\n",
    "            self.sdm1.write(bs_board, bs_actions, weight=weight)\n",
    "                \n",
    "    def next_move(self, step, board, debug=False):\n",
    "        x = self.sdm_move(step, board)\n",
    "        if x is not None:\n",
    "            if self.debug:\n",
    "                print('SDM')\n",
    "            return x\n",
    "        if self.debug:\n",
    "            print('Random')\n",
    "        return self.random_move(step, board)\n",
    "    \n",
    "    def bs_actions_to_rewards(self, bs_actions):\n",
    "        rewards = []\n",
    "        bit = 0\n",
    "        qty = self.qty_per_action\n",
    "        for idx in range(9):\n",
    "            x = 0\n",
    "            for i in range(qty):\n",
    "                x += bs_actions.get_bit(bit)\n",
    "                bit += 1\n",
    "            rewards.append(x)\n",
    "        return rewards\n",
    "    \n",
    "    def sdm_move(self, step, board, debug=False):\n",
    "        bs_board = self.board_to_bitstring(board)\n",
    "        bs_actions = self.sdm1.read(bs_board)\n",
    "        rewards = self.bs_actions_to_rewards(bs_actions)\n",
    "\n",
    "        if self.debug:\n",
    "            print_board(board)\n",
    "            print(rewards)\n",
    "\n",
    "        for idx, reward in sorted(enumerate(rewards), key=lambda x: x[1], reverse=True):\n",
    "            if board[idx] == empty:\n",
    "                if self.debug:\n",
    "                    print('idx={} reward={}'.format(idx, reward))\n",
    "                self.stats['sdm'] += 1\n",
    "                return idx\n",
    "        return None\n",
    "    \n",
    "    def random_move(self, step, board):\n",
    "        self.stats['random'] += 1\n",
    "        v = []\n",
    "        for idx, x in enumerate(board):\n",
    "            if x == empty:\n",
    "                v.append(idx)\n",
    "        return random.choice(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_board(board):\n",
    "    i = 0\n",
    "    while i < len(board):\n",
    "        print('|' + board[i:i+3] + '|')\n",
    "        i += 3\n",
    "    print('')\n",
    "\n",
    "def check_all_equal(*args):\n",
    "    if len(set(args)) == 1 and args[0] != empty:\n",
    "        return True\n",
    "    return False\n",
    "        \n",
    "def check_for_winner(board):\n",
    "    for i in range(3):\n",
    "        if check_all_equal(board[3*i+0], board[3*i+1], board[3*i+2]):\n",
    "            return board[3*i+0]\n",
    "        \n",
    "        if check_all_equal(board[3*0+i], board[3*1+i], board[3*2+i]):\n",
    "            return board[3*0+i]\n",
    "\n",
    "    if check_all_equal(board[3*0+0], board[3*1+1], board[3*2+2]):\n",
    "        return board[3*0+0]\n",
    "    \n",
    "    if check_all_equal(board[3*0+2], board[3*1+1], board[3*2+0]):\n",
    "        return board[3*0+2]\n",
    "    \n",
    "    return None\n",
    "\n",
    "def board_flip(board):\n",
    "        return board.translate(flip_table)\n",
    "\n",
    "def play(p1, p2, shuffle=True):\n",
    "    board = ' '*9\n",
    "    end = False\n",
    "    players = [('X', p1), ('O', p2)]\n",
    "    if shuffle:\n",
    "        random.shuffle(players)\n",
    "    index = 0\n",
    "    step = 0\n",
    "    sequence = []\n",
    "    winner = None\n",
    "    while winner is None and step < 9:\n",
    "        cur_name, cur_player = players[index]\n",
    "        \n",
    "        if cur_name == 'X':\n",
    "            idx = cur_player.next_move(step, board)\n",
    "        else:\n",
    "            idx = cur_player.next_move(step, board_flip(board))\n",
    "        \n",
    "        if board[idx] != empty:\n",
    "            cur_player.on_invalid_move()\n",
    "        \n",
    "        new_board = board[:idx] + cur_name + board[idx+1:]\n",
    "        sequence.append((cur_name, idx, board, new_board))\n",
    "        board = new_board\n",
    "        \n",
    "        winner = check_for_winner(board)\n",
    "        \n",
    "        index = (index+1)%2\n",
    "        step += 1\n",
    "\n",
    "    return winner, sequence"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "def run(pA, pB, n, show=False, debug=False, shuffle=True, learning=True, offset=0):\n",
    "    wins = defaultdict(int)\n",
    "    for i in range(n):\n",
    "        winner, seq = play(pA, pB, shuffle=shuffle)\n",
    "\n",
    "        wins[winner] += 1\n",
    "\n",
    "        if not debug:\n",
    "            clear_output(wait=True)\n",
    "        else:\n",
    "            print('')\n",
    "            \n",
    "        print('Game #{:5d}: {}  {} {}'.format(i+1+offset, list(wins.items()), list(pA.stats.items()), list(pB.stats.items())))\n",
    "\n",
    "        if debug:\n",
    "            for i, (name, action, board_before, board_after) in enumerate(seq):\n",
    "                print('step={}'.format(i))\n",
    "                print_board(board_before)\n",
    "                \n",
    "        if show:\n",
    "            print('')\n",
    "            print_board(seq[-1][3])\n",
    "            print('')\n",
    "\n",
    "        if learning:\n",
    "            pA.on_finish(winner, seq)\n",
    "            pB.on_finish(winner, seq)\n",
    "    return wins"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "bits, radius = 1000, 451\n",
    "#bits, radius = 256, 103\n",
    "\n",
    "sample = 1000000\n",
    "scanner_type = sdmlib.SDM_SCANNER_OPENCL\n",
    "\n",
    "address_space = sdmlib.AddressSpace.init_random(bits, sample)\n",
    "\n",
    "#counter0 = sdmlib.Counter.init_zero(bits, sample)\n",
    "#sdm0 = sdmlib.SDM(address_space, counter0, radius, scanner_type)\n",
    "\n",
    "counter1 = sdmlib.Counter.init_zero(bits, sample)\n",
    "sdm11 = sdmlib.SDM(address_space, counter1, radius, scanner_type)\n",
    "\n",
    "counter2 = sdmlib.Counter.init_zero(bits, sample)\n",
    "sdm12 = sdmlib.SDM(address_space, counter2, radius, scanner_type)\n",
    "\n",
    "bs_to_boards = {}\n",
    "boards_to_bs = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "scanner_type = sdmlib.SDM_SCANNER_OPENCL\n",
    "#sdm0 = sdmlib.SDM(address_space, counter0, radius, scanner_type)\n",
    "sdm11 = sdmlib.SDM(address_space, counter1, radius, scanner_type)\n",
    "sdm12 = sdmlib.SDM(address_space, counter2, radius, scanner_type)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdm1 = SDMPlayer(None, sdm11, bs_to_boards, boards_to_bs)\n",
    "sdm2 = SDMPlayer(None, sdm12, bs_to_boards, boards_to_bs)\n",
    "rnd = Player()\n",
    "hum = HumanPlayer()\n",
    "smt = SmartPlayer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "resultsSmart = []\n",
    "resultsRandom = []\n",
    "resultsSDM = []\n",
    "resultsMixed = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdm1.debug = False\n",
    "for i in range(30):\n",
    "    resultsSmart.append(run(sdm1, smt, 100, show=True, offset=100*i, learning=False))\n",
    "    %time run(sdm1, smt, 100, show=True, offset=100*i, learning=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "sdm1.debug = False\n",
    "for i in range(30):\n",
    "    resultsRandom.append(run(sdm1, rnd, 100, show=True, offset=100*i, learning=False))\n",
    "    %time run(sdm1, rnd, 100, show=True, offset=100*i, learning=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdm1.debug = False\n",
    "for i in range(20):\n",
    "    resultsSDM.append(run(sdm1, sdm2, 100, show=True, offset=100*i, learning=False))\n",
    "    %time run(sdm1, sdm2, 100, show=True, offset=100*i, learning=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Game # 1000: [('X', 15), (None, 79), ('O', 6)]  [('sdm', 48401)] []\n",
      "\n",
      "|XOX|\n",
      "|OXX|\n",
      "|OXO|\n",
      "\n",
      "\n",
      "CPU times: user 3.01 s, sys: 608 ms, total: 3.62 s\n",
      "Wall time: 5.65 s\n"
     ]
    }
   ],
   "source": [
    "sdm1.debug = False\n",
    "for i in range(10):\n",
    "    other = random.choice([sdm2, smt, rnd])\n",
    "    resultsMixed.append(run(sdm1, other, 100, show=True, offset=100*i, learning=False))\n",
    "    %time run(sdm1, other, 100, show=True, offset=100*i, learning=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%time run(sdm1, sdm2, 500, show=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "sdm1.debug = True\n",
    "run(sdm1, hum, 1, show=True, debug=True, learning=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "sdm1.debug = True\n",
    "run(sdm1, rnd, 1, show=True, debug=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%time run(sdm2, smt, 1000, show=True, learning=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdmX.next_move(0, ' '*9, debug=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x3152c4a50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def draw(results):\n",
    "    import numpy as np\n",
    "\n",
    "    pos = np.arange(len(results))\n",
    "    width = 0.35\n",
    "\n",
    "    plt.figure(figsize=(8, 6), dpi=100)\n",
    "    winX = [100.0*x['X']/(x['X'] + x['O'] + x[None]) for x in results]\n",
    "    draw = [100.0*x[None]/(x['X'] + x['O'] + x[None]) for x in results]\n",
    "    winO = [100.0*x['O']/(x['X'] + x['O'] + x[None]) for x in results]\n",
    "    #plt.bar(pos, winX, width, color='k')\n",
    "    #plt.bar(pos, draw, width, bottom=winX, color='b')\n",
    "    #plt.bar(pos, winO, width)\n",
    "    #plt.bar(pos+width, [100.0*x['X']/(x['X'] + x['O'] + x[None]) for x in resultsRandom], width, color='y')\n",
    "    \n",
    "    plt.stackplot(pos, winO)\n",
    "    \n",
    "    #plt.stackplot(pos, winO, draw, winX, labels=['Lose', 'Draw', 'Win'])\n",
    "    #plt.legend()\n",
    " \n",
    "    plt.grid()\n",
    "    #plt.ylabel('% of loses')\n",
    "    plt.xlabel('Number of games (hundreds)');\n",
    "\n",
    "draw(resultsMixed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = resultsSmart[0]\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "counter = sdm1.next_move(0, 'X O  O   ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "counter = sdm11.read_counter(boards_to_bs[' '*9])\n",
    "bs = counter.to_bitstring(0)\n",
    "counter_values = [counter.counter[0][i] for i in range(bits)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i, x in enumerate(counter_values):\n",
    "    if bs.get_bit(i):\n",
    "        assert(x >= 0)\n",
    "    else:\n",
    "        assert(x <= 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i, x in enumerate(counter_values):\n",
    "    print('{:4d} {:10d}'.format(i, x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
